﻿Imports System.Text.RegularExpressions
Imports 地图商家采集系统
Public Class CMapBaiDu
    Inherits CMap
    Implements IMap
    Public Sub New(mapTask As Model_Task, callback As Action(Of CProductInfo))
        task = mapTask
        UpdateView = callback
    End Sub
#Region "百度采集方法"
    Public Sub Deal() Implements IMap.Deal
        Log($"{MapMode.BaiDu.GetDescription}信息解析中...")
        Dim areas = task.Areas
        For Each area In areas
            Dim t = UtilsHelper.ConvertDateTimeToInt()
            Dim wd = area.City
            If wd.IsNullOrEmpty() Then wd = area.Country
            Dim realURL = "https://map.baidu.com/?qt=cur" & "&wd=" & Uri.EscapeDataString(wd) & $"&t={t}&dtype=1"
            Dim code = GetCode(realURL)
            '通过城市码得到HTML,并获取列表页相关信息类BaiDuListInfo
            GetProducts(code, area)
        Next
    End Sub
    ''' <summary>
    ''' 获取城市码
    ''' </summary>
    ''' <param name="url"></param>
    ''' <returns></returns>
    Private Overloads Function GetCode(url As String) As String
        Dim count As Integer = 1
        Dim html As String = ""
        Do
            'https://map.baidu.com/?qt=cur&wd=%E6%9F%B3%E5%B7%9E&t=1620961716219&dtype=1
            'https://map.baidu.com/?qt=cur&wd=%E9%9D%92%E5%B1%B1%E6%B9%96%E5%8C%BA&t=1620961762648&dtype=1
            html = Sy.Text.Encode.RemoveEscape_Java(Sy.Net.Factory.Http(url).Get())
            count += 1
        Loop While count < 5 Or html.Length = 0
        If Not html.Length > 0 Then
            Log("URL：" & url & "--->>>发现城市码解析有误")
            Return ""
        End If
        Dim spliter = """code"":"
        If html.Contains(spliter) Then
            Dim code = Split(html, spliter)(1)
            Return Split(code, ",")(0)
        Else
            Log("URL：" & url & "--->>>发现城市码解析有误")
            Return ""
        End If
    End Function
    ''' <summary>
    ''' 获取列表页的信息
    ''' </summary>
    ''' <param name="code"></param>
    Private Sub GetProducts(code As String, area As CAreaInfo)
        Dim city = area.City
        Dim keywords = task.keyWords
        For Each k As CKeyword In keywords
            Dim FlagPageEnd As Boolean = False, Page = -1
            Dim infoCount As Integer = 0
            Dim prePage As String = ""
            Dim success As Integer = 0
            Dim FailCount As Integer = 0
            Do
                success = 0
                Page += 1
                Dim key = Uri.EscapeDataString(k.Keyword)
                Dim url = $"https://map.baidu.com/?newmap=1&reqflag=pcmap&biz=1&from=webmap&da_par=direct&pcevaname=pc4.1&qt=s&da_src=searchBox.button&wd={key}&c={code}&src=0&wd2=&pn={Page}"
                Dim count As Integer = 1
                Dim html As String = ""
                Dim exp As Exception
                Do
                    exp = Nothing
                    html = Sy.Text.Encode.RemoveEscape_HTML(
                        Sy.Text.Encode.RemoveEscape_Java(Sy.Net.Factory.Http(url).SetExceptionHandle(Function() exp).Get())) 'GetHtml(url, Exception:=exp)
                    count += 1
                Loop While exp IsNot Nothing And count < 5
                If exp Is Nothing Then
                    Dim arrSpliter = "acc_flag"
                    If html.Length < 0 Or Not html.Contains(arrSpliter) Or prePage = html Then
                        'Dim bInfos = GetListInfo(html, k.Keyword, task.TaskMode.GetDescription, url, city)
                        Log("关键字：" & k.Keyword & "未采集到信息,请确认")
                        FlagPageEnd = True
                    Else
#Region "采集列表页信息"
                        prePage = html
                        Dim items = html.Split({arrSpliter}, StringSplitOptions.RemoveEmptyEntries)
                        For i = 1 To items.Count - 1
                            Dim item = items(i)
                            Dim SyItem As Sy.String = item
                            Dim addrSpliter = """addr"":"""
                            Dim address As String = ""
                            Dim areaNameSpliter = """area_name"":"""
                            Dim areaName = ""
                            Dim workplane As String = ""
                            Dim title As String = ""
                            Dim phone As String = ""
                            Dim mobile As String = ""
                            Dim x As Double = 0
                            Dim y As Double = 0
                            If item.Contains(areaNameSpliter) Then
                                areaName = Regex.Unescape(SyItem.Mid(areaNameSpliter, """"))
                            End If
                            
#Region "地址"
                            If item.Contains(addrSpliter) Then address = Split(item, addrSpliter)(1).Split({""""}, StringSplitOptions.None)(0)
#End Region
#Region "坐标"
                            Dim xSpliter = """diPointX"":"
                            Dim ySpliter = """diPointY"":"
                            If SyItem.Contains(xSpliter) AndAlso SyItem.Contains(ySpliter) Then
                                x = SyItem.SplitEx(xSpliter, 1).BeforeFirst(",")
                                x /= 100
                                Dim StrY = SyItem.SplitEx(ySpliter, 1).BeforeFirst(",")
                                If StrY.Contains("}") Then StrY = StrY.BeforeFirst("}")
                                y = StrY
                                y /= 100
                                End If
                                workplane = "X:" & x & "|Y:" & y
#End Region
#Region "标题"
                            Dim titleSpliter = "ext_display"
                            If item.Contains(titleSpliter) Then
                                title = Split(item, titleSpliter)(1)
                                Dim nameSpliter = """name"":"""
                                If item.Contains(nameSpliter) Then
                                    title = Split(item, nameSpliter)(1).Split({""""}, StringSplitOptions.None)(0)
                                End If
                            End If
#End Region

#Region "手机号"
                            Dim phoneSpliter = """phone"":"""
                            If item.Contains(phoneSpliter) Then mobile = Split(item, phoneSpliter)(1).Split({""""}, StringSplitOptions.None)(0).Trim
                            '座机号
                            Dim telSpliter = """tel"":"""
                            If item.Contains(telSpliter) Then phone = Split(item, telSpliter)(1).Split({""""}, StringSplitOptions.None)(0).Trim
#End Region
                            Dim pidSpilter = "primary_uid"":"""
                            Dim uidSpliter = """uid"":"""
#Region "访问详情页所需ID(备用，目前不需要,使用时，关闭注释即可)"
                            'Dim pid = ""
                            'Dim uid = ""
                            'If item.Contains(pidSpilter) Then
                            '    Dim temp = Split(item, pidSpilter)(1)
                            '    pid = Split(temp, """")(0)
                            '    If temp.Contains(uidSpliter) Then uid = Split(Split(temp, uidSpliter)(1), """")(0)
                            'End If
#End Region
#Region "采集过滤,添加"
#End Region
                            If FilterResult(title, phone, mobile, address) AndAlso FilterKeywordResult(title, task.FilterKeywords) Then
                                Dim info = New CProductInfo(address, title, workplane, city, k.Keyword, MapMode.BaiDu.GetDescription, url, phone, mobile, areaName)
                                success += If(info.Add(), 1, 0)
                                UpdateView(info)
                            End If
                        Next
#End Region
                        If items.Count <= 1 Then FlagPageEnd = True
                        If success = 0 Then
                            FailCount += 1
                            If FailCount > 3 Then FlagPageEnd = True
                        Else
                            FailCount = 0
                        End If
                    End If
                Else
                    Log("采集超时异常")
                    FlagPageEnd = True
                End If
            Loop Until FlagPageEnd
        Next
    End Sub
#End Region
End Class


